﻿using PlanckTime.Entity;
using System;
using System.Security;
using Veripark.Data;
using Veripark.Data.Entity;
using Veripark.Mobile.ServiceProxy;
using Veripark.Mobile.ServiceProxy.Model;

namespace PlanckTime.Server
{
    public class Services
    {
        private void EnsureUser()
        {
            if (User == null)
            {
                throw new SecurityException();
            }
        }

        private static User User
        {
            get
            {
                return BaseUser.Current as User;
            }
            set
            {
                BaseUser.Current = value;
            }
        }

        private static Guid administratorRoleId;

        private static Guid AdministratorRoleId
        {
            get
            {
                if (administratorRoleId == Guid.Empty)
                {
                    lock (typeof(Services))
                    {
                        if (administratorRoleId == Guid.Empty)
                        {
                            administratorRoleId = BasicEntity.Restore<Role>(Role.NameField == "Administrator").Id;
                        }
                    }
                }
                return administratorRoleId;
            }
        }

        private void EnsureAdministrator()
        {
            EnsureUser();

            if (User.RoleId != AdministratorRoleId)
            {
                throw new SecurityException();
            }
        }

        [PublicInvokable]
        [CreateSession]
        public User Authenticate(User user)
        {
            User result = BasicEntity.Restore<User>
            (
                User.NameField == user.Name &
                User.PinField == user.Pin
            );

            if (result != null)
            {
                User = result;
            }

            return result;
        }

        [PublicInvokable]
        public BasicEntity Save(BasicEntity entity)
        {
            EnsureAdministrator();

            entity.Save();

            return entity;
        }

        [PublicInvokable]
        public BasicEntityCollection GetTasks(Task parent)
        {
            EnsureUser();

            return BasicEntityCollection.Restore(typeof(Task), Task.ParentIdField == parent.Id);
        }

        [PublicInvokable]
        public string GetUserDisplayName(User user)
        {

            EnsureUser();

            User result = BasicEntity.Restore<User>
            (
                User.IdField == user.Id
            );

            if (result != null)
            {
                return result.DisplayName;
            }

            return string.Empty;
        }

        [PublicInvokable]
        public BasicEntityCollection GetTaskData(Task task)
        {
            EnsureUser();

            return BasicEntityCollection.Restore(typeof(TaskData), TaskData.TaskIdField == task.Id);
        }

        [PublicInvokable]
        public BasicEntityCollection GetEventLog(Task task)
        {
            EnsureUser();

            return BasicEntityCollection.Restore(typeof(EventLog), EventLog.TaskIdField == task.Id);
        }

    }
}